package controller;

import helper.AngepassteException;
import helper.Mail;

import java.io.IOException;

import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.GregorianCalendar;
import java.util.Random;
import model.Benutzer;
import model.BenutzerRepository;
import model.PwVergessenSchnittstelle;
import model.PwZuruecksetzenLink;

/**
 * Dieses Servlet lässt den Benutzer sein Passwort, per link in einer E-Mail,
 * zurücksetzen.
 * 
 * @author Kaith Menken
 */
@WebServlet("/PasswortVergessen")
public class PasswortVergessen extends SessionControll {
	private static final long serialVersionUID = 1L;
	public static final String serverAdresse = "http://localhost:8080/";

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public PasswortVergessen() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		String email = request.getParameter("email-adresse"); //die Emailadresse wird zwischengespeichert
	
		if (email != null) { //prüfe ob Benutzer eine Emailadresse eingegeben hat
			
			Benutzer benutzer;
			try { //prüfe ob Emailadresse im System vorhanden. Anschließend wird ein Link generiert
				benutzer = BenutzerRepository.getInstance()
						.getBenutzerNachEmail(email);
				if (benutzer != null) { //prüfe ob es einen Benutzer zu der eingegebenen Emailadresse gibt
					
					request.setAttribute("benutzerregistriert", "true");
					PwVergessenSchnittstelle.abgelaufeneLinksLoeschen(); //alle abgelaufenen Links werden gelöscht
					Random generator = new Random();
					String random;
					PwZuruecksetzenLink l;

					do {
						random = "";

						for (int i = 0; i < 60; i++) {
							int v = generator.nextInt(10);
							random += v;
						}

						l = PwVergessenSchnittstelle.getLink(random); //prüft ob dieser Random-Wert noch nicht vergeben ist

					} while (l != null);
					/**
					 * if-else gibt feedback ob der Benutzer schon einen Link
					 * hatte und löscht diesen
					 */
					if (PwVergessenSchnittstelle.getLink(benutzer.getId()) != null) {
						
						PwVergessenSchnittstelle.linkLoeschen(PwVergessenSchnittstelle.getLink(benutzer.getId()).random);//löscht alten Link des Benutzers falls vorhanden
						System.out.println("link gelöscht");
						request.setAttribute("lgeloescht", true);

					} else {
						request.setAttribute("lgeloescht", false);
					}

					PwZuruecksetzenLink link = new PwZuruecksetzenLink();
					link.random = random;
					link.benutzerId = benutzer.getId();
					link.erstelltzeit = (new GregorianCalendar())
							.getTimeInMillis();
					PwVergessenSchnittstelle.setLink(link); //Neuer Link wird gespeichert

					String genLink = "http://"
							+ request.getServerName() + (80==request.getServerPort()?"":(":"+request.getServerPort()))
							+ "/ModulManagementSystem/PasswortVergessen?link="
							+ random + "";

					Mail.passwortAendern(benutzer.getEmail(), genLink); //Der generierte Link wird nun an den Benutzer gesendet
				} else {
					request.setAttribute("benutzerregistriert", "false"); //Wenn das Objekt "Benutzer" leer ist wird diese else aufgerufen und das Attribut gespeichert, dass die Emailadresse nicht im System ist
				}
				RequestDispatcher view;
				view = request.getRequestDispatcher("PasswortVergessen.jsp"); 
				view.forward(request, response);
				
			} catch (ClassNotFoundException e) {
				new helper.Logging("Fehler F100",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
				response.sendRedirect("Fehler?weiterleitung=PasswortVergessen&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F100)");
			} catch (SQLException e) {
				new helper.Logging("Fehler F101",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
				response.sendRedirect("Fehler?weiterleitung=PasswortVergessen&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F101)");
			} catch (Exception e) {
				new helper.Logging("Fehler F102",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
				response.sendRedirect("Fehler?weiterleitung=PasswortVergessen&fehler=Es gab einen Fehler mit dem Mail-Service! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F102)");
			}

			
		} 
		
		else if (request.getParameter("link") != null) { //Beim klicken des Links wird nun dieser auf richtigkeit überprüft und man wird weitergeleitet auf die Passwort-Ändern Seite
		String pzlink = request.getParameter("link");
		try {
			PwVergessenSchnittstelle.abgelaufeneLinksLoeschen();
			PwZuruecksetzenLink benutzerObjekt = PwVergessenSchnittstelle.getLink(pzlink);
			if (benutzerObjekt != null) {
				String benutzerLink = benutzerObjekt.random;
				request.setAttribute("echterlink", "true");
				request.setAttribute("benutzerLink", benutzerLink);
			} else{
				throw new AngepassteException("");
			}
			RequestDispatcher view;
			view = request.getRequestDispatcher("PasswortAendern.jsp");
			view.forward(request, response);
		} catch (ClassNotFoundException e) {
			new helper.Logging("Fehler F103",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
			response.sendRedirect("Fehler?weiterleitung=PasswortVergessen&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F103)");
		} catch (SQLException e) {
			new helper.Logging("Fehler F104",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
			response.sendRedirect("Fehler?weiterleitung=PasswortVergessen&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F104)");
		} catch (AngepassteException e){
			new helper.Logging("Fehler F105",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
			response.sendRedirect("Fehler?weiterleitung=PasswortVergessen&fehler=Der Link ist ungültig geworden. Bitte kontaktieren Sie einen Administrator. (F105)");
		}

	} else if (request.getParameter("zubearbeitenderLink") != null){ //Passwort wird zurückgesetzt
		String zubearbeitenderLink = request.getParameter("zubearbeitenderLink");
		if(request.getParameter("passwort").equals(request.getParameter("passwortwiederholt"))){ //wenn Passwort und die Wiederholung übereinstimmen wird das Passwort in die Datenbank eingespeichert
			try {
				PwZuruecksetzenLink benutzerObjekt = PwVergessenSchnittstelle.getLink(zubearbeitenderLink);
				int benutzerID = benutzerObjekt.benutzerId;
				Benutzer benutzer = benutzerRepository.getBenutzerNachId(benutzerID);
				try {
					benutzer.setPasswort(Benutzer.getHash(request.getParameter("passwort")));
				} catch (NoSuchAlgorithmException e) {
					new helper.Logging("Fehler F107",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				benutzerRepository.saveBenutzer(benutzer);
				request.setAttribute("benutzerGespeichert", "true");
				PwVergessenSchnittstelle.linkLoeschen(zubearbeitenderLink);
				RequestDispatcher view;
				view = request.getRequestDispatcher("PasswortAendern.jsp");
				view.forward(request, response);
				
			} catch (ClassNotFoundException e) {
				new helper.Logging("Fehler F105",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
				response.sendRedirect("Fehler?weiterleitung=PasswortVergessen&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F105)");
			} catch (SQLException e) {
				new helper.Logging("Fehler F106",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
				response.sendRedirect("Fehler?weiterleitung=PasswortVergessen&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F106)");
			}
		}
	}
		
		else { 
			RequestDispatcher view;
			view = request.getRequestDispatcher("PasswortVergessen.jsp");
			view.forward(request, response);
	
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
